// import com.alibaba.druid.sql.ast.SQLExpr;
// import com.alibaba.druid.sql.ast.SQLExprImpl;
// import com.alibaba.druid.sql.ast.SQLReplaceable;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "SQLValuesExpr.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/listTran.h"
#include "../../../utils/ifeq.h"
#include "SQLListExpr.h"

SQLValuesExpr::SQLValuesExpr()
{
  values = SQLListExpr_list_ptr();
}
SQLListExpr_list_ptr SQLValuesExpr::getValues()
{
  return values;
}

// @Override
void SQLValuesExpr::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLValuesExpr)))
  {
    SQLObject_list_ptr  tmp = ListTran::tran_class<SQLListExpr, SQLObject>(values);
    acceptChild(visitor, tmp);
  }
  visitor->endVisit(SharedObject(SQLValuesExpr));
}

// @Override
bool SQLValuesExpr::equals(Object_ptr o)
{
  if (this == o.get())
  {
    return true;
  }
  if (o == nullptr || getClass() != o->getClass())
  {
    return false;
  }

  std::shared_ptr<SQLValuesExpr> that = std::dynamic_pointer_cast<SQLValuesExpr>(o);

  return IFEQ::ifeq<SQLListExpr_ptr>(values, that->values);
}

// @Override
int SQLValuesExpr::hashCode()
{
  return values->size();
}

// @Override
SQLObject_ptr SQLValuesExpr::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SQLValuesExpr>(new SQLValuesExpr());
  std::shared_ptr<SQLValuesExpr> x = std::dynamic_pointer_cast<SQLValuesExpr>(clone_tmp);
  // SQLValuesExpr x = new SQLValuesExpr();

  for (SQLListExpr_ptr value : *values)
  {
    SQLListExpr_ptr value2 = std::dynamic_pointer_cast<SQLListExpr>(value->clone());
    value2->setParent(x);
    x->values->push_back(value2);
  }

  return x;
}

// @Override
BOOL_ptr SQLValuesExpr::replace(SQLExpr_ptr expr, SQLExpr_ptr target)
{
  auto it_values = values->begin();
  for (int i = 0; i < values->size(); i++)
  {
    std::advance(it_values, i);
    if ((*it_values) == expr)
    {
      target->setParent(SharedObject(SQLValuesExpr));
      (*it_values) = std::dynamic_pointer_cast<SQLListExpr>(target);
      return BOOL::TRUE;
    }
  }
  return BOOL::FALSE;
}

// @Override
SQLObject_list_ptr  SQLValuesExpr::getChildren()
{
  SQLObject_list_ptr  tmp = ListTran::tran_class<SQLListExpr, SQLObject>(values);
  return tmp;
}
